package com.liuzy.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.security.MessageDigest;

@Slf4j
public class FileUtil {
    // 文件上传保存的目录
    public static File dir;

    static {
        dir = new File(System.getProperty("user.home"), "upload-dir");
        if (!dir.exists()) {
            dir.mkdirs();
        }
    }

    // 切几块
    public static int slice(long length, long size) {
        return (int) Math.ceil(1D * length / size);
    }

    // 文件真实路径
    public static File absoluteFile(String fileId) {
        return new File(dir, fileId);
    }

    // 创建文件锁
    public static final Object lock = new Object();

    // 加锁创建临时文件
    public static File gotTempFile(String fileId, long length) throws IOException {
        File file = new File(dir, fileId + ".tmp");
        if (!file.exists()) {
            synchronized (lock) {
                if (!file.exists()) {
                    log.info("创建临时文件 {} 长度 {}", file.getPath(), length);
                    try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
                        raf.setLength(length);
                    }
                }
            }
        }
        return file;
    }

    // 写临时文件
    public static boolean writeTempFile(File temp, MultipartFile blockFile, long blockOffset) {
        try (InputStream is = blockFile.getInputStream();
             RandomAccessFile raf = new RandomAccessFile(temp, "rw")) {
            raf.seek(blockOffset);
            int length;
            for (byte[] buff = new byte[4096]; (length = is.read(buff)) != -1; ) {
                raf.write(buff, 0, length);
            }
            return true;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return false;
        }
    }

    public static String getMD5(File file, long start, long length) {
        try (FileInputStream fis = new FileInputStream(file)) {
            MessageDigest MD5 = MessageDigest.getInstance("MD5");
            fis.skip(start);
            byte[] buff = new byte[(int) length];
            fis.read(buff);
            MD5.update(buff, 0, (int) length);
            return new String(Hex.encodeHex(MD5.digest()));
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
